﻿// Decompiled with JetBrains decompiler
// Type: TaleWorlds.CampaignSystem.Election.KingSelectionKingdomDecision
// Assembly: TaleWorlds.CampaignSystem, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: E85F8C15-4DF6-4E9C-A58A-29177E40D07A
// Assembly location: D:\steam\steamapps\common\Mount & Blade II Bannerlord\bin\Win64_Shipping_Client\TaleWorlds.CampaignSystem.dll

using Helpers;
using System;
using System.Collections.Generic;
using System.Linq;
using TaleWorlds.CampaignSystem.Actions;
using TaleWorlds.CampaignSystem.CharacterDevelopment;
using TaleWorlds.Core;
using TaleWorlds.Library;
using TaleWorlds.Localization;
using TaleWorlds.SaveSystem;

#nullable disable
namespace TaleWorlds.CampaignSystem.Election
{
  public class KingSelectionKingdomDecision : KingdomDecision
  {
    [SaveableField(1)]
    private Clan _clanToExclude;

    internal static void AutoGeneratedStaticCollectObjectsKingSelectionKingdomDecision(
      object o,
      List<object> collectedObjects)
    {
      ((KingdomDecision) o).AutoGeneratedInstanceCollectObjects(collectedObjects);
    }

    protected override void AutoGeneratedInstanceCollectObjects(List<object> collectedObjects)
    {
      base.AutoGeneratedInstanceCollectObjects(collectedObjects);
      collectedObjects.Add((object) this._clanToExclude);
    }

    internal static object AutoGeneratedGetMemberValue_clanToExclude(object o)
    {
      return (object) ((KingSelectionKingdomDecision) o)._clanToExclude;
    }

    public KingSelectionKingdomDecision(Clan proposerClan, Clan clanToExclude = null)
      : base(proposerClan)
    {
      this._clanToExclude = clanToExclude;
    }

    public override bool IsAllowed()
    {
      return Campaign.Current.Models.KingdomDecisionPermissionModel.IsKingSelectionDecisionAllowed(this.Kingdom);
    }

    public override int GetProposalInfluenceCost()
    {
      return Campaign.Current.Models.DiplomacyModel.GetInfluenceCostOfProposingWar(this.ProposerClan);
    }

    public override TextObject GetGeneralTitle()
    {
      TextObject generalTitle = new TextObject("{=ZYSGp5vO}King of {KINGDOM_NAME}");
      generalTitle.SetTextVariable("KINGDOM_NAME", this.Kingdom.Name);
      return generalTitle;
    }

    public override TextObject GetSupportTitle()
    {
      TextObject supportTitle = new TextObject("{=B0uKPW9S}Vote for the next ruler of {KINGDOM_NAME}");
      supportTitle.SetTextVariable("KINGDOM_NAME", this.Kingdom.Name);
      return supportTitle;
    }

    public override TextObject GetChooseTitle()
    {
      TextObject chooseTitle = new TextObject("{=L0Oxzkfw}Choose the next ruler of {KINGDOM_NAME}");
      chooseTitle.SetTextVariable("KINGDOM_NAME", this.Kingdom.Name);
      return chooseTitle;
    }

    public override TextObject GetSupportDescription()
    {
      TextObject supportDescription = new TextObject("{=XGuDyJMZ}{KINGDOM_NAME} will decide who will bear the crown as the next ruler. You can pick your stance regarding this decision.");
      supportDescription.SetTextVariable("KINGDOM_NAME", this.Kingdom.Name);
      return supportDescription;
    }

    public override TextObject GetChooseDescription()
    {
      TextObject chooseDescription = new TextObject("{=L0Oxzkfw}Choose the next ruler of {KINGDOM_NAME}");
      chooseDescription.SetTextVariable("KINGDOM_NAME", this.Kingdom.Name);
      return chooseDescription;
    }

    public override bool IsKingsVoteAllowed => false;

    protected override bool CanProposerClanChangeOpinion() => true;

    public override float CalculateMeritOfOutcome(DecisionOutcome candidateOutcome)
    {
      float meritOfOutcome = 1f;
      foreach (Clan clan in (List<Clan>) this.Kingdom.Clans)
      {
        if (clan.Leader != Hero.MainHero)
          meritOfOutcome += this.CalculateMeritOfOutcomeForClan(clan, candidateOutcome);
      }
      return meritOfOutcome;
    }

    public float CalculateMeritOfOutcomeForClan(Clan clan, DecisionOutcome candidateOutcome)
    {
      float num1 = 0.0f;
      Hero king = ((KingSelectionKingdomDecision.KingSelectionDecisionOutcome) candidateOutcome).King;
      if (king.Clan == this.Kingdom.RulingClan)
      {
        if (clan.Leader.GetTraitLevel(DefaultTraits.Authoritarian) > 0)
          num1 += 3f;
        else if (clan.Leader.GetTraitLevel(DefaultTraits.Oligarchic) > 0)
          num1 += 2f;
        else
          ++num1;
      }
      List<float> list = this.Kingdom.Clans.Select<Clan, float>((Func<Clan, float>) (t => Campaign.Current.Models.DiplomacyModel.GetClanStrength(t))).OrderByDescending<float, float>((Func<float, float>) (t => t)).ToList<float>();
      int num2;
      float num3 = (float) (num2 = 6) / (list[0] - list[list.Count - 1]);
      float num4 = (float) ((double) num2 / 2.0 - (double) num3 * (double) list[0]);
      float num5 = Campaign.Current.Models.DiplomacyModel.GetClanStrength(king.Clan) * num3 + num4;
      return MathF.Clamp(num1 + num5, -3f, 8f);
    }

    public override IEnumerable<DecisionOutcome> DetermineInitialCandidates()
    {
      KingSelectionKingdomDecision selectionKingdomDecision = this;
      Dictionary<Clan, float> source = new Dictionary<Clan, float>();
      foreach (Clan clan in (List<Clan>) selectionKingdomDecision.Kingdom.Clans)
      {
        if (Campaign.Current.Models.DiplomacyModel.IsClanEligibleToBecomeRuler(clan) && clan != selectionKingdomDecision._clanToExclude)
          source.Add(clan, Campaign.Current.Models.DiplomacyModel.GetClanStrength(clan));
      }
      foreach (KeyValuePair<Clan, float> keyValuePair in source.OrderByDescending<KeyValuePair<Clan, float>, float>((Func<KeyValuePair<Clan, float>, float>) (t => t.Value)).Take<KeyValuePair<Clan, float>>(3))
        yield return (DecisionOutcome) new KingSelectionKingdomDecision.KingSelectionDecisionOutcome(keyValuePair.Key.Leader);
    }

    public override Clan DetermineChooser() => this.Kingdom.RulingClan;

    public override float DetermineSupport(Clan clan, DecisionOutcome possibleOutcome)
    {
      return this.CalculateMeritOfOutcomeForClan(clan, possibleOutcome) * 10f;
    }

    public override void DetermineSponsors(MBReadOnlyList<DecisionOutcome> possibleOutcomes)
    {
      foreach (DecisionOutcome possibleOutcome in (List<DecisionOutcome>) possibleOutcomes)
      {
        DecisionOutcome decisionOutcome;
        Clan clan = ((KingSelectionKingdomDecision.KingSelectionDecisionOutcome) (decisionOutcome = possibleOutcome)).King.Clan;
        decisionOutcome.SetSponsor(clan);
      }
    }

    public override void ApplyChosenOutcome(DecisionOutcome chosenOutcome)
    {
      Hero king = ((KingSelectionKingdomDecision.KingSelectionDecisionOutcome) chosenOutcome).King;
      if (king != king.Clan.Leader)
        ChangeClanLeaderAction.ApplyWithSelectedNewLeader(king.Clan, king);
      ChangeRulingClanAction.Apply(this.Kingdom, king.Clan);
    }

    public override TextObject GetSecondaryEffects()
    {
      return new TextObject("{=!}All supporters gains some relation with each other.");
    }

    public override void ApplySecondaryEffects(
      MBReadOnlyList<DecisionOutcome> possibleOutcomes,
      DecisionOutcome chosenOutcome)
    {
    }

    public override TextObject GetChosenOutcomeText(
      DecisionOutcome chosenOutcome,
      KingdomDecision.SupportStatus supportStatus,
      bool isShortVersion = false)
    {
      TextObject parent = new TextObject("{=JQligd8z}The council of the {KINGDOM} has chosen {KING.NAME} as the new ruler.");
      parent.SetTextVariable("KINGDOM", this.Kingdom.Name);
      StringHelpers.SetCharacterProperties("KING", ((KingSelectionKingdomDecision.KingSelectionDecisionOutcome) chosenOutcome).King.CharacterObject, parent);
      return parent;
    }

    public override DecisionOutcome GetQueriedDecisionOutcome(
      MBReadOnlyList<DecisionOutcome> possibleOutcomes)
    {
      return possibleOutcomes.OrderByDescending<DecisionOutcome, float>((Func<DecisionOutcome, float>) (k => k.Merit)).FirstOrDefault<DecisionOutcome>();
    }

    public class KingSelectionDecisionOutcome : DecisionOutcome
    {
      [SaveableField(100)]
      public readonly Hero King;

      internal static void AutoGeneratedStaticCollectObjectsKingSelectionDecisionOutcome(
        object o,
        List<object> collectedObjects)
      {
        ((DecisionOutcome) o).AutoGeneratedInstanceCollectObjects(collectedObjects);
      }

      protected override void AutoGeneratedInstanceCollectObjects(List<object> collectedObjects)
      {
        base.AutoGeneratedInstanceCollectObjects(collectedObjects);
        collectedObjects.Add((object) this.King);
      }

      internal static object AutoGeneratedGetMemberValueKing(object o)
      {
        return (object) ((KingSelectionKingdomDecision.KingSelectionDecisionOutcome) o).King;
      }

      public KingSelectionDecisionOutcome(Hero king) => this.King = king;

      public override TextObject GetDecisionTitle()
      {
        TextObject parent = new TextObject("{=4G3Aeqna}{KING.NAME}");
        StringHelpers.SetCharacterProperties("KING", this.King.CharacterObject, parent);
        return parent;
      }

      public override TextObject GetDecisionDescription()
      {
        TextObject parent = new TextObject("{=FTjKWm8s}{KING.NAME} should rule us");
        StringHelpers.SetCharacterProperties("KING", this.King.CharacterObject, parent);
        return parent;
      }

      public override string GetDecisionLink() => (string) null;

      public override ImageIdentifier GetDecisionImageIdentifier() => (ImageIdentifier) null;
    }
  }
}
